using System;
using System.Collections.Generic;
using System.Text;

namespace Avanzis.Helpers.PersistentObjects
{
    
    public interface ISessionScope : IDisposable
	{
		/// <summary>
		/// Returns the <see cref="FlushAction"/> defined 
		/// for this scope
		/// </summary>
		FlushAction FlushAction { get; }
		
		/// <summary>
		/// Returns the <see cref="SessionScopeType"/> defined 
		/// for this scope
		/// </summary>
		SessionScopeType ScopeType { get; }
		
		/// <summary>
		/// Flushes the sessions that this scope 
		/// is maintaining
		/// </summary>
		void Flush();

		/// <summary>
		/// This method is invoked when no session was available
		/// at and the <see cref="Castle.ActiveRecord.Framework.ISessionFactoryHolder"/>
		/// just created one. So it registers the session created 
		/// within this scope using a key. The scope implementation
		/// shouldn't make any assumption on what the key
		/// actually is as we reserve the right to change it 
		/// <seealso cref="IsKeyKnown"/>
		/// </summary>
		/// <param name="key">an object instance</param>
		/// <param name="session">An instance of <c>ISession</c></param>
		void RegisterSession(object key, Session session);

		/// <summary>
		/// This method is invoked when the 
		/// <see cref="Castle.ActiveRecord.Framework.ISessionFactoryHolder"/>
		/// instance needs a session instance. Instead of creating one it interrogates
		/// the active scope for one. The scope implementation must check if it
		/// has a session registered for the given key. 
		/// <seealso cref="RegisterSession"/>
		/// </summary>
		/// <param name="key">an object instance</param>
		/// <returns><c>true</c> if the key exists within this scope instance</returns>
		bool IsKeyKnown(object key);

		/// <summary>
		/// This method should return the session instance associated with the key.
		/// </summary>
		/// <param name="key">an object instance</param>
		/// <returns>the session instance or null if none was found</returns>
		Session GetSession(object key);

		/// <summary>
		/// Implementors should return true if they
		/// want that their scope implementation 
		/// be in charge of creating the session
		/// </summary>
		bool WantsToCreateTheSession { get; }

		/// <summary>
		/// If the <see cref="WantsToCreateTheSession"/> returned
		/// <c>true</c> then this method is invoked to allow 
		/// the scope to create a properly configured session
		/// </summary>
		/// <param name="sessionFactory">From where to open the session</param>
		/// <param name="interceptor">the NHibernate interceptor</param>
		/// <returns>the newly created session</returns>
		Session OpenSession(SessionFactory sessionFactory);
	}

    public enum SessionScopeType
    {
        Undefined,
        Simple,
        Transactional,
        Custom
    }

    /// <summary>
    /// Pendent
    /// </summary>
    [Serializable]
    public enum FlushAction
    {
        /// <summary>
        /// Original behavior. Changes are persisted at the 
        /// end or before some queries.
        /// </summary>
        Auto,
        /// <summary>
        /// Flush need to be controlled manually. Best choice
        /// for readonly operations
        /// </summary>
        Never
    }
}
